package com.smart.manager.union.mall.repository;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.util.ObjectUtil;
import com.smart.common.entities.core.BaseSearch;
import com.smart.common.entities.core.Page;
import com.smart.common.entities.domain.OrderAddress;
import com.smart.manager.member.entities.enums.CoinAccountEvent;
import com.smart.manager.member.entities.models.MemberProfileAccount;
import com.smart.manager.member.entities.views.MemberView;
import com.smart.manager.member.repository.MemberAccountRepository;
import com.smart.manager.member.repository.MemberProfileAddressRepository;
import com.smart.manager.union.egg.enums.EggOrderState;
import com.smart.manager.union.mall.body.RUnionMallOrder;
import com.smart.manager.union.mall.enums.MallGoodsState;
import com.smart.manager.union.mall.enums.MallOrderState;
import com.smart.manager.union.mall.models.UnionMallGoods;
import com.smart.manager.union.mall.models.UnionMallOrder;
import com.smart.manager.union.mall.models.query.QUnionMallGoods;
import com.smart.manager.union.mall.models.query.QUnionMallOrder;
import com.smart.service.remind.RemindService;
import com.smart.utils.SqlUtil;
import com.smart.wap.bodys.OrderBody;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 帮助中心
 *
 * @author leo
 * @date 2023/07/26
 */
@Service
@Log4j2
@RequiredArgsConstructor
public class UnionMallOrderRepository {

    private final MemberAccountRepository memberAccountRepository;
    private final MemberProfileAddressRepository memberProfileAddressRepository;
    private final RemindService remindService ;
    /**
     * 查询搜索
     *
     * @param search 搜索
     * @return {@link Page}<{@link UnionMallOrder}>
     */
    public Page<UnionMallOrder> pageList(RUnionMallOrder.SearchBody search) {
        QUnionMallOrder query = new QUnionMallOrder();

        Opt.ofBlankAble(search.getKeyword()).ifPresent(x -> query.raw("address::text like '%" + x + "%'  "));
        Opt.ofBlankAble(search.getState()).ifPresent(x -> query.state.eq(x));
        Opt.ofBlankAble(search.getSubmitRange()).ifPresent(x -> {
            LocalDateTime[] ts = SqlUtil.formatDateTimeRange(x);
            query.submitTime.between(ts[0], ts[1]);

        });
        Opt.ofBlankAble(search.getSendRangeRange()).ifPresent(x -> {
            LocalDateTime[] ts = SqlUtil.formatDateTimeRange(x);
            query.submitTime.between(ts[0], ts[1]);

        });

        Opt.ofBlankAble(search.getExpressName()).ifPresent(x -> query.expressName.contains(x));
        Opt.ofBlankAble(search.getExpressCode()).ifPresent(x -> query.expressCode.contains(x));
        query.order().id.desc().setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<UnionMallOrder>().load(query.findPagedList());
    }


    public Page<UnionMallOrder> getMyPageList(Long memberId, BaseSearch search) {
        QUnionMallOrder query = new QUnionMallOrder();
        query.member.id.eq(memberId).order().id.desc().setFirstRow(search.firstRow()).setMaxRows(search.maxRows());
        return new Page<UnionMallOrder>().load(query.findPagedList());

    }


    /**
     * 创建实物订单
     */
    public void createOrder(Long memberId, RUnionMallOrder.CreateBody body) {

        UnionMallGoods goods = new QUnionMallGoods().id.eq(body.getGoodsId()).setMaxRows(1).findOne();
        Assert.notNull(goods, "购买失败:商品信息不存在");
        Assert.equals(goods.getState(), MallGoodsState.ZC, "购买失败:商品信息已下架");
        Assert.isTrue(goods.getStockTotal() > body.getQuantity(), "购买失败:商品库存不足");
        int needPayFee = goods.getDisPrice() * body.getQuantity();
        MemberProfileAccount account = memberAccountRepository.getAccount(memberId);
        Assert.isTrue(account.getCoinBalance() >= needPayFee, "购买失败:账户余额不足");


        OrderAddress orderAddress = memberProfileAddressRepository.readOrderAddress(memberId);
        MallOrderState state = ObjectUtil.isNotNull(orderAddress) ? MallOrderState.T10 : MallOrderState.T0;
        MemberView memberView = new MemberView().setId(memberId);
        // 开始创建订单
        UnionMallOrder mallOrder = new UnionMallOrder().setGoods(goods)
                .setQuantity(body.getQuantity())
                .setMember(memberView).setState(state)
                .setExpressFee(BigDecimal.ZERO).setAddress(orderAddress)
                .setSubmitTime(LocalDateTime.now());
        mallOrder.insert();

        // 开始扣减库存和增加销量
        goods.setSaleCount(goods.getSaleCount() + body.getQuantity());
        goods.setStockTotal(goods.getStockTotal() - body.getQuantity());
        goods.update();
        // 开始扣减账户余额
        memberAccountRepository.saveEvent(memberId, CoinAccountEvent.MALL, needPayFee , "购买"+goods.getTitle());

        // 发送消息
        remindService.sendWhenMallOrderCreate(memberId,  mallOrder);
    }

    public void updateMallOrderAddress(Long memberId, OrderBody.UpdateAddressBody body) {
        UnionMallOrder record = new QUnionMallOrder().id.eq(body.getId()).member.id.eq(memberId).setMaxRows(1).findOne();
        Assert.notNull(record, "订单不存在");
        Assert.equals(MallOrderState.T0, record.getState(), "当前订单禁止修改地址");
        record.setState(MallOrderState.T10).setAddress(body.getAddress()).update();

    }


    /**
     * 完善订单快递信息
     */
    public void replenishExpress(RUnionMallOrder.ReplenishExpress body) {
        UnionMallOrder record = new QUnionMallOrder().id.eq(body.getId()).setMaxRows(1).findOne();
        Assert.notNull(record, "订单不存在");
        Assert.equals(EggOrderState.T10, record.getState(), "当前订单禁止发货");
        BeanUtil.copyProperties(body, record);
        record.setState(MallOrderState.T20).setSendTime(LocalDateTime.now()).update();

    }
}
